package com.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hospital.common.UserRole;
import com.hospital.entity.Department;
import com.hospital.entity.User;
import com.hospital.mapper.UserMapper;
import com.hospital.service.DepartmentService;
import com.hospital.service.UserService;
import com.hospital.util.UserContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Objects;

/**
 * 用户服务实现类
 *
 * @author Hospital Management System
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final PasswordEncoder passwordEncoder;
    private final DepartmentService departmentService;

    @Override
    public List<User> getUsers(String keyword) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (keyword != null && !keyword.trim().isEmpty()) {
            wrapper.like("username", keyword)
                   .or().like("name", keyword)
                   .or().like("phone", keyword);
        }
        return list(wrapper);
    }

    @Override
    public Map<String, Object> getUsersWithPagination(String keyword, Integer role, Integer status, Integer page, Integer size) {
        // 创建分页对象
        Page<User> pageObj = new Page<>(page, size);
        
        // 构建查询条件
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w.like("username", keyword)
                           .or().like("name", keyword)
                           .or().like("phone", keyword)
                           .or().like("email", keyword));
        }
        
        // 角色过滤
        if (role != null) {
            wrapper.eq("role", role);
        }
        
        // 状态过滤
        if (status != null) {
            wrapper.eq("status", status);
        }
        
        // 按创建时间降序排列
        wrapper.orderByDesc("create_time");
        
        // 执行分页查询
        IPage<User> pageResult = page(pageObj, wrapper);
        
        // 填充科室信息（对于医生）
        List<User> users = pageResult.getRecords();
        fillDepartmentInfoForUsers(users);
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", users);
        result.put("total", pageResult.getTotal());
        result.put("page", pageResult.getCurrent());
        result.put("size", pageResult.getSize());
        result.put("pages", pageResult.getPages());
        
        return result;
    }

    @Override
    public void resetPassword(Long userId) {
        User user = getById(userId);
        if (user != null) {
            // 重置为默认密码123456并加密
            user.setPassword(passwordEncoder.encode("123456"));
            updateById(user);
            log.info("重置用户{}密码成功", userId);
        }
    }

    @Override
    public void changeStatus(Long userId, Integer status) {
        User user = getById(userId);
        if (user != null) {
            user.setStatus(status);
            updateById(user);
            log.info("修改用户{}状态为{}", userId, status);
        }
    }

    @Override
    public User findByUsername(String username) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        return getOne(wrapper);
    }

    @Override
    public User findByUsernameAndRole(String username, Integer role) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username).eq("role", role);
        return getOne(wrapper);
    }

    // ==================== 医生相关功能实现 ====================

    @Override
    public User getCurrentDoctor() {
        User currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }
        
        if (!UserRole.DOCTOR.equals(currentUser.getRole())) {
            throw new RuntimeException("当前用户不是医生");
        }
        
        // 填充科室信息
        fillDepartmentInfo(currentUser);
        
        log.info("获取当前登录医生信息: {}", currentUser.getUsername());
        return currentUser;
    }

    @Override
    public List<User> getDoctors(String keyword) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role", UserRole.DOCTOR);
        
        List<User> doctors = list(queryWrapper);
        
        if (doctors.isEmpty()) {
            return doctors;
        }
        
        // 获取所有科室信息
        List<Long> departmentIds = doctors.stream()
                .map(User::getDepartmentId)
                .filter(id -> id != null)
                .distinct()
                .collect(Collectors.toList());
        
        Map<Long, Department> departmentMap = null;
        if (!departmentIds.isEmpty()) {
            List<Department> departments = departmentService.listByIds(departmentIds);
            departmentMap = departments.stream()
                    .collect(Collectors.toMap(Department::getId, dept -> dept));
        }
        
        // 填充科室信息并过滤
        final Map<Long, Department> finalDepartmentMap = departmentMap;
        List<User> result = doctors.stream()
                .peek(doctor -> {
                    // 填充科室信息
                    if (doctor.getDepartmentId() != null && finalDepartmentMap != null) {
                        Department department = finalDepartmentMap.get(doctor.getDepartmentId());
                        if (department != null) {
                            doctor.setDepartmentName(department.getName());
                            doctor.setDepartmentCode(department.getCode());
                        }
                    }
                })
                .filter(doctor -> {
                    // 应用关键词过滤
                    if (!StringUtils.hasText(keyword)) {
                        return true;
                    }
                    
                    return (doctor.getName() != null && doctor.getName().contains(keyword)) ||
                           (doctor.getDoctorNo() != null && doctor.getDoctorNo().contains(keyword)) ||
                           (doctor.getPhone() != null && doctor.getPhone().contains(keyword)) ||
                           (doctor.getDepartmentName() != null && doctor.getDepartmentName().contains(keyword));
                })
                .collect(Collectors.toList());
        
        return result;
    }

    @Override
    public List<User> getDoctorsByDepartment(Long departmentId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role", UserRole.DOCTOR)
                   .eq("department_id", departmentId)
                   .eq("status", 1);
        
        List<User> doctors = list(queryWrapper);
        
        // 填充科室信息
        for (User doctor : doctors) {
            fillDepartmentInfo(doctor);
        }
        
        return doctors;
    }

    @Override
    public User getDoctorDetail(Long doctorId) {
        User doctor = getById(doctorId);
        if (doctor == null || !UserRole.DOCTOR.equals(doctor.getRole())) {
            return null;
        }
        
        // 填充科室信息
        fillDepartmentInfo(doctor);
        
        return doctor;
    }

    @Override
    public Map<String, Object> getDoctorsWithPagination(String keyword, Long departmentId, Integer status, Integer page, Integer size) {
        log.info("开始查询医生列表，参数：keyword={}, departmentId={}, status={}, page={}, size={}", 
                 keyword, departmentId, status, page, size);
        
        try {
            // 创建分页对象
            Page<User> pageObj = new Page<>(page, size);
            
            // 构建查询条件
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("deleted", 0)
                       .eq("role", UserRole.DOCTOR);
            
            // 添加关键词搜索
            if (StringUtils.hasText(keyword)) {
                log.info("添加关键词筛选条件: {}", keyword);
                queryWrapper.and(wrapper -> wrapper
                    .like("name", keyword)
                    .or()
                    .like("phone", keyword)
                    .or()
                    .like("email", keyword)
                    .or()
                    .like("doctor_no", keyword));
            }
            
            // 添加科室筛选
            if (departmentId != null) {
                log.info("添加科室筛选条件: {}", departmentId);
                queryWrapper.eq("department_id", departmentId);
            }
            
            // 添加状态筛选
            if (status != null) {
                log.info("添加状态筛选条件: {}", status);
                queryWrapper.eq("status", status);
            }
            
            // 按工号排序
            queryWrapper.orderByAsc("doctor_no");
            
            // 打印最终的SQL条件
            String sqlSegment = queryWrapper.getSqlSegment();
            log.info("最终的SQL条件: {}", sqlSegment);
            
            // 执行分页查询
            IPage<User> pageResult = page(pageObj, queryWrapper);
            
            // 获取分页数据
            List<User> doctors = pageResult.getRecords();
            log.info("查询结果总数: {}", pageResult.getTotal());
            
            // 填充科室信息
            fillDepartmentInfo(doctors);
            
            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("list", doctors);
            result.put("total", pageResult.getTotal());
            result.put("page", pageResult.getCurrent());
            result.put("size", pageResult.getSize());
            result.put("pages", pageResult.getPages());
            
            return result;
        } catch (Exception e) {
            log.error("查询医生列表时发生错误: {}", e.getMessage(), e);
            throw e;
        }
    }

    // ==================== 管理员相关功能实现 ====================

    @Override
    public User getCurrentAdmin() {
        User currentUser = UserContext.getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录");
        }
        
        if (!UserRole.ADMIN.equals(currentUser.getRole())) {
            throw new RuntimeException("当前用户不是管理员");
        }
        
        log.info("获取当前登录管理员信息: {}", currentUser.getUsername());
        return currentUser;
    }

    @Override
    public List<User> getAdmins(String keyword) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role", UserRole.ADMIN);
        
        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(wrapper -> wrapper.like("username", keyword)
                                              .or().like("name", keyword)
                                              .or().like("admin_no", keyword));
        }
        
        return list(queryWrapper);
    }

    // ==================== 私有方法 ====================

    /**
     * 为用户填充科室信息
     */
    private void fillDepartmentInfo(User user) {
        if (user != null && user.getDepartmentId() != null) {
            Department department = departmentService.getById(user.getDepartmentId());
            if (department != null) {
                user.setDepartmentName(department.getName());
                user.setDepartmentCode(department.getCode());
            }
        }
    }

    /**
     * 为用户列表批量填充科室信息
     */
    private void fillDepartmentInfoForUsers(List<User> users) {
        if (users == null || users.isEmpty()) {
            return;
        }
        
        // 获取所有需要填充科室信息的用户的科室ID
        List<Long> departmentIds = users.stream()
                .filter(user -> user.getDepartmentId() != null)
                .map(User::getDepartmentId)
                .distinct()
                .collect(Collectors.toList());
        
        if (departmentIds.isEmpty()) {
            return;
        }
        
        // 批量查询科室信息
        List<Department> departments = departmentService.listByIds(departmentIds);
        Map<Long, Department> departmentMap = departments.stream()
                .collect(Collectors.toMap(Department::getId, dept -> dept));
        
        // 填充科室信息
        users.forEach(user -> {
            if (user.getDepartmentId() != null) {
                Department department = departmentMap.get(user.getDepartmentId());
                if (department != null) {
                    user.setDepartmentName(department.getName());
                    user.setDepartmentCode(department.getCode());
                }
            }
        });
    }

    /**
     * 填充科室信息
     */
    private void fillDepartmentInfo(List<User> doctors) {
        if (doctors == null || doctors.isEmpty()) {
            return;
        }
        
        // 收集所有科室ID
        List<Long> departmentIds = doctors.stream()
                .map(User::getDepartmentId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        
        if (!departmentIds.isEmpty()) {
            // 批量查询科室信息
            List<Department> departments = departmentService.listByIds(departmentIds);
            Map<Long, Department> departmentMap = departments.stream()
                    .collect(Collectors.toMap(Department::getId, dept -> dept));
            
            // 填充科室信息
            for (User doctor : doctors) {
                if (doctor.getDepartmentId() != null) {
                    Department dept = departmentMap.get(doctor.getDepartmentId());
                    if (dept != null) {
                        doctor.setDepartmentName(dept.getName());
                    }
                }
            }
        }
    }

    @Override
    public long countNewUsersToday() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 获取今天的开始时间和结束时间
        LocalDateTime startOfDay = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime endOfDay = startOfDay.plusDays(1);
        
        queryWrapper.between("create_time", startOfDay, endOfDay);
        return count(queryWrapper);
    }

    @Override
    public long countByRole(Integer role) {
        if (role == null) {
            return 0L;
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role", role)
                   .eq("status", 1)  // 只统计有效用户
                   .eq("deleted", 0); // 排除已删除用户
        return count(queryWrapper);
    }
} 